/*
 * table_CppPPCondition.c
 *
 *  Created on: 2012/03/31
 *      Author: guanxiaoying
 */
#include "../../parser/coredef.h"

/* KIND_PPCONDITION	*/
typedef struct _PPCONDITION
{
	union {
	DOUBLE		dValue;		/* 2 */
	S4		s4Value;	/* 3 */
	U4      u4Value;
	}result;
	AST     astLocScp;
	AST		astLeftNode;	/* 4 */
	AST     astRightNode;
	U2		ulKind;	/* 5 */
	U2		ulOpKind;	/* 5 */
}PPCONDITION, *PPPCONDITION;



#define TableSize  (sizeof(PPCONDITION))
#define TableType  PPPCONDITION
#define stTable stPPCondExpManager.memoryBlocks
#define maxTable stPPCondExpManager.maxRecordNum
#define  maxNumPerBlk  (stPPCondExpManager.astMaxNum_Block)
/* private field */

static TABLEMANAGER stPPCondExpManager = {
//		U4                  usIdx;
		0,
//		PSZ				    con_pszName;    constant
		__FILE__,
//		U2					con_usSize;		constant
		TableSize,
//		U2					block_num;	　　　　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_Block;     １回設定のみ
		0,
//		S4					astTabNum_LastPage; 　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_LastPage;     Reset clear  際　要
		0,
//		U4					ulMaxByte;	　　　　　　　　　　クリアしない
		0,
//		U4					con_minPageSize;　　　　　　　　　　constant
		0
};

static VOID resetListener( U4  procid, U2 index )
{
	if( procid == stPPCondExpManager.u4Idx )
	{
		if( index > 0 && index < MAX_VOLUMN_OF_TABLE )
		{
			stTable[ index-1] = NULL;
		}
	}
}
static TableType core_getTable( AST index )
{
	TableType temp = (TableType)Check_Com( &stPPCondExpManager,  resetListener, index );
	if( temp != NULL ){ return &temp[index%maxNumPerBlk]; } return NULL;
}
static BOOL ClearTable( VOID )
{
	return Clear_Com( &stPPCondExpManager );
}
static BOOL ResetTable( VOID )
{
	return Reset_Com( &stPPCondExpManager );
}
static BOOL AllocTable( AST astReqArg )
{
	return AllocTable_Com( &stPPCondExpManager, astReqArg, resetListener );
}
static AST getMaxLineNum( VOID ){
	return maxTable;
}
/* give up the way that defining get/set function pointer in the struct,
 * because of memory volume.
 */
//ACCESS_DOUBLE_FIELD dbValue;
static DOUBLE getDbValue( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulOpKind == xPPTOKEN_DOUBLE ){
		return pTbl->result.dValue;
	}else if( pTbl->ulOpKind == xPPTOKEN_ULONG ){
		return (DOUBLE)pTbl->result.u4Value;
	}
	return (DOUBLE)pTbl->result.s4Value;
}
static DOUBLE setDbValue( AST index, DOUBLE value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulOpKind != 0 && pTbl->ulOpKind != xPPTOKEN_DOUBLE ){
		Throw_MemoryError( &stPPCondExpManager, DATA_SETTING_MISS, index, pTbl->ulOpKind );
	}
	pTbl->ulOpKind = xPPTOKEN_DOUBLE;
	return pTbl->result.dValue = value;
}
static U4 getULValue( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulOpKind == xPPTOKEN_DOUBLE ){
		return (U4)pTbl->result.dValue;
	}else if( pTbl->ulOpKind == xPPTOKEN_ULONG ){
		return (U4)pTbl->result.u4Value;
	}
	return (U4)pTbl->result.s4Value;
}
static U4 setULValue( AST index, U4 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulOpKind != 0 && pTbl->ulOpKind != xPPTOKEN_ULONG ){
		Throw_MemoryError( &stPPCondExpManager, DATA_SETTING_MISS, index, pTbl->ulOpKind );
	}
	pTbl->ulOpKind = xPPTOKEN_ULONG;
	return pTbl->result.u4Value = value;
}
static S4 getSLValue( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulOpKind == xPPTOKEN_DOUBLE ){
		return (S4)pTbl->result.dValue;
	}else if( pTbl->ulOpKind == xPPTOKEN_ULONG ){
		return (S4)pTbl->result.u4Value;
	}
	return (S4)pTbl->result.s4Value;

}
static S4 setSLValue( AST index, S4 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	if( pTbl->ulOpKind != 0 && pTbl->ulOpKind != xPPTOKEN_LONG ){
		Throw_MemoryError( &stPPCondExpManager, DATA_SETTING_MISS, index, pTbl->ulOpKind );
	}
	pTbl->ulOpKind = xPPTOKEN_LONG;
	return pTbl->result.s4Value = value;
}

//ACCESS_IDX_FIELD  locScp;
static AST getLocScope( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astLocScp;
}
static AST setLocScope( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astLocScp = value;
}
//ACCESS_IDX_FIELD  leftNode;
static AST getLeftNode( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astLeftNode;
}
static AST setLeftNode( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astLeftNode = value;
}
//ACCESS_IDX_FIELD  rightNode;
static AST getRightNode( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astRightNode;
}
static AST setRightNode( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astRightNode = value;
}
//ACCESS_U4_FIELD   nodeKind;
static U4 getNodeKind( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ulKind;
}
static U4 setNodeKind( AST index, U4 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ulKind = value;
}
static U4 getOpKind( AST index ){
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ulOpKind;
}
static U4 setOpKind( AST index, U4 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->ulOpKind = value;
}
const PPCONDITIONACCESS stCorePPConditionAccess = {
		ClearTable,
		ResetTable,
		AllocTable,
		getMaxLineNum,
		{
				getDbValue,
				setDbValue
		},
		{
				getULValue,
				setULValue
		},
		{
				getSLValue,
				setSLValue
		},
		{
				getLocScope,
				setLocScope
		},
		{
				getLeftNode,
				setLeftNode
		},
		{
				getRightNode,
				setRightNode
		},
		{
				getNodeKind,
				setNodeKind
		},
		{
				getOpKind,
				setOpKind
		}
};
